/**
 * 
 */
package com.lehecai.core.lottery.fetcher.lotterydraw.impl.worker;

import com.lehecai.core.lottery.LotteryType;
import com.lehecai.core.lottery.fetcher.FetcherLotteryTypeMap;
import com.lehecai.core.lottery.fetcher.FetcherType;
import com.lehecai.core.lottery.fetcher.lotterydraw.LotteryDraw;
import com.lehecai.core.lottery.fetcher.lotterydraw.LotteryDrawPrizeItem;
import com.lehecai.core.util.CoreFetcherUtils;
import net.sf.json.JSONObject;
import org.htmlparser.Node;
import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.filters.TagNameFilter;
import org.htmlparser.nodes.TextNode;
import org.htmlparser.tags.LinkTag;
import org.htmlparser.tags.TableColumn;
import org.htmlparser.tags.TableRow;
import org.htmlparser.tags.TableTag;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;

import java.util.*;


/**
 * 全国开奖页面Qihoo通用抓取实现类
 * @author cs
 *
 */
public class CountryLotteryDrawFetchWorkerQihoo extends AbstractLotteryDrawFetchWorker {

	private static Map<LotteryType, String> defaultUrlMap = new HashMap<LotteryType, String>();
	private static Map<LotteryType, String> historyUrlMap = new HashMap<LotteryType, String>();

	static {
		//超级大乐透
		defaultUrlMap.put(LotteryType.DLT, "http://cp.360.cn/kj/slt.html");
		historyUrlMap.put(LotteryType.DLT, "http://cp.360.cn/kaijiang/bonusinfo?lotId=120029&issue=%s");

		//双色球
		defaultUrlMap.put(LotteryType.SSQ, "http://cp.360.cn/kj/ssq.html");
		historyUrlMap.put(LotteryType.SSQ, "http://cp.360.cn/kaijiang/bonusinfo?lotId=220051&issue=%s");
	}

	protected String siteName = "Qihoo";
	protected String lotteryScope = "全国开奖";
	protected String volumeOfSalesName = "本期销量：";
	protected String jackpotName = "奖池滚存：";
	protected String lotteryMiddleKeyValue = "";//特殊情况用以区分页面同名不同的彩种,如胜负彩任九
	//开奖结果所在行号 0为第一行
	protected int resultRowNumber = 1;
	protected int volumeOfSalesRowNumber = 2;

	private static final String BASE_URL = "http://cp.360.cn/kj/";
	private static final String RESULT_URL = "http://cp.360.cn/kj/kaijiang.html";

	public CountryLotteryDrawFetchWorkerQihoo(LotteryType lotteryType) {
		super(lotteryType);
	}
	
	@Override
	public LotteryDraw fetchResult(String phase) {
		LotteryType lotteryType = this.getLotteryType();
		String url = RESULT_URL;
		String pageInfo = "列表页面"+url;
		String encoding = "GBK";
		String logHeader = "=="+lotteryScope+"=="+siteName+"=="+pageInfo+"==抓取=="+getLotteryType().getName()+"==";
		logger.info(logHeader+"开始==");
		
		LotteryDraw lotteryDraw=null;
		String data=null;
		Parser parser=null;
		
		data = CoreFetcherUtils.URLGet(url, null, encoding);
		if (data == null || data.indexOf("404 Not Found") > 0) {
			logger.error(logHeader+"data is null or 404 Not Found");
			return null;
		}
		parser= Parser.createParser(data,  encoding);
		
		//String filterName = "table";
		//NodeFilter tableFilter = new TagNameFilter(filterName);
		NodeFilter tagNameFilter = new TagNameFilter("table");
		NodeList nodeList = null;
		try {
			nodeList = parser.extractAllNodesThatMatch(tagNameFilter);
		} catch (ParserException e2){
			logger.error(logHeader+"数据解析错误=="+e2.getMessage(), e2);
			return null;
		}
		try{
			TableTag tableTag = (TableTag)nodeList.elementAt(0);
			TableRow[] rowsPhase=tableTag.getRows();
			TableColumn[] columnPhase = null;
			for(int i=1;i<rowsPhase.length;i++){
				columnPhase=rowsPhase[i].getColumns();
				if(columnPhase.length == 4){
					String lotteryName = null;
					//获取彩种、彩期
					NodeList childList = columnPhase[0].getChildren().elementAt(0).getChildren();
                    Node firstChildNode = null;
                    Node lastChildNode = null;
                    if (childList.size() == 3) {
                        firstChildNode = childList.elementAt(1).getFirstChild();
                        lastChildNode = childList.elementAt(1).getLastChild();
                    } else if (childList.size() == 2) {
                        firstChildNode = childList.elementAt(0).getFirstChild();
                        lastChildNode = childList.elementAt(0).getLastChild();
                    }
                    String lotteryPhase = null;
                    if(firstChildNode instanceof LinkTag){
                        LinkTag linkNode = (LinkTag)firstChildNode;
                        lotteryName = linkNode.getLinkText().trim();
                        lotteryPhase = lastChildNode.toPlainTextString().split("第")[1].split("期")[0].trim();
                    }
					//判断是否是所抓类型
					if(getLotteryType().getValue() == FetcherLotteryTypeMap.getLotteryValueByKey(FetcherType.T_QIHOO.getName()+lotteryMiddleKeyValue+lotteryName)){
						if(lotteryPhase==null){
							logger.error(logHeader+"页面抓取的彩期号({})不存在,返回null==",lotteryPhase);
							return null;
						}

                        //获取开奖结果
                        childList = columnPhase[1].getChildren().elementAt(0).getChildren();
                        Node drawNode = childList.elementAt(0);
                        NodeList drawResultNode = drawNode.getFirstChild().getChildren();
                        StringBuilder resultBuilder = new StringBuilder();
                        for (int j = 0; j < drawResultNode.size(); j++) {
                            Node resultElement = drawResultNode.elementAt(j);
                            if (resultElement instanceof TextNode) {
                                resultBuilder.append(resultElement.getText().trim()).append(",");
                            }
                        }
                        if(resultBuilder.length() == 0){
                            logger.error(logHeader+"页面开奖结果(html内容:"+columnPhase[3].toHtml()+")信息不存在或有错误,返回null");
                            return null;
                        }
                        String result = resultBuilder.substring(0, resultBuilder.length() - 1);

                        //获取开奖详情连接
//                        Node detailLinkNode = drawNode.getLastChild().getFirstChild();
//                        String detailLink = null;
//                        if(detailLinkNode instanceof LinkTag){
//                            LinkTag linkNode = (LinkTag)detailLinkNode;
//                            detailLink = linkNode.getLink().trim();
//                        }

                        //获取开奖时间，奖池
                        String timeDraw = null;
                        String jackpot = null;
                        NodeList children = columnPhase[1].getChildren().elementAt(0).getChildren().elementAt(1).getFirstChild().getChildren();
                        Node drawTimeNode = children.elementAt(0);
                        timeDraw = drawTimeNode.getText().split("\\(")[0].trim();
                        Calendar c = Calendar.getInstance();
                        int year = c.get(Calendar.YEAR);
                        timeDraw = year + "-" + timeDraw;

                        //指定彩期为null，抓取列表页面的彩期数据
						if(phase==null||phase.isEmpty()){
							phase = lotteryPhase;
							//当前期可写入详细url，以便抓取对应的详细信息
//							this.setLotteryDetailUrl(lotteryType, BASE_URL + detailLink);
						}else{
							if(lotteryPhase.equals(phase)){
								phase = lotteryPhase;
							}else{
								logger.error(logHeader+"指定抓取的彩期号({})与页面抓取的彩期号({})不一致,返回null==",phase,lotteryPhase);
								return null;
							}
						}

						lotteryDraw = new LotteryDraw();
						lotteryDraw.setPhase(phase);
						lotteryDraw.setResult(result);
						//格式化时间串
						lotteryDraw.setTimeDraw(CoreFetcherUtils.formatTimeDraw(timeDraw));
						lotteryDraw.setJackpot(jackpot);
						lotteryDraw.setLotteryType(getLotteryType());

						logger.info(logHeader+lotteryDraw.getLotteryOpenResultLogMsg());
						break;
					}
				}
			}//end for
		}catch(Exception e1){
			logger.error(logHeader+"页面错误=="+e1.getMessage(),e1);
			return null;
		}
		if(lotteryDraw==null){
			logger.info(logHeader+"未抓取到相关开奖结果信息,返回null==");
		}
		logger.info(logHeader+"结束==");
		return lotteryDraw;
	}

	@Override
	public LotteryDraw fetchResultDetail(String phase) {
        String longPhase = phase;
		String url = this.getResultDetailUrl(longPhase);
		if(url==null || url.isEmpty()){
			logger.error("=="+lotteryScope+"=="+siteName+"==详细页面==抓取=="+getLotteryType().getName()+"==期号："+phase+"==详细地址不存在，返回null");
			return null;
		}
		String pageInfo = "详细页面"+url;
		String encoding = "GBK";
		String logHeader = "=="+lotteryScope+"=="+siteName+"=="+pageInfo+"==抓取=="+getLotteryType().getName()+"==";
		
		logger.info(logHeader+"开始==");
		LotteryDraw lotteryDraw=null;
		
		String data=null;
		Parser parser=null;
		
		data = CoreFetcherUtils.URLGet(url, null, encoding);
		if (data == null || data.indexOf("404 Not Found") > 0) {
			logger.error(logHeader+"data is null or 404 Not Found");
			return null;
		}
        JSONObject dataJson = null;
		try {
            dataJson = JSONObject.fromObject(data);
		} catch (Exception e) {
			logger.error(logHeader+"数据解析错误=="+e.getMessage(), e);
			return null;
		}
		//抓期数,彩票名称,开奖时间,开奖结果,销量,奖池
		//String lotteryName = null;
		String timeDraw = null;
		String result = null;
		String volumeOfSales=null;
		String jackpot=null;
		String tableColumnData = null;
		TableTag titleTableTag = new TableTag();

        //开奖时间
        timeDraw = dataJson.getString("time").split("\\(")[0].trim();

        //开奖结果
        String resultString = dataJson.getString("code");
        StringBuilder resultBuilder = new StringBuilder();
        String[] resultCodes = resultString.split("</li><li>");
        for (String resultCode : resultCodes) {
            String replaceCode = resultCode.replace("</em>", "").replace("</li>", "");
            String resultNum = replaceCode.substring(replaceCode.lastIndexOf(">")+1);
            resultBuilder.append(resultNum.trim()).append(",");
        }
        if(resultBuilder.length() == 0){
            logger.error(logHeader+"解析开奖结果不存在，未取到开奖结果==");
            return null;
        }
        result = resultBuilder.substring(0, resultBuilder.length() - 1);

        //销量
        try {
            volumeOfSales = dataJson.getString("sale").replace(",", "");
        } catch (Exception e) {
            volumeOfSales="0";
        }

        //奖池
        try {
            String money = dataJson.getString("money").split("</strong>")[0];
            jackpot = money.substring(money.lastIndexOf(">")+1).replace(",", "");
        } catch (Exception e) {
            jackpot="0";
        }

		//抓取开奖详情
        String levelData = dataJson.getString("level");
        if (null != levelData && !levelData.trim().isEmpty()) {
			List<LotteryDrawPrizeItem> resultDetail = new ArrayList<LotteryDrawPrizeItem>();
            String[] splitResultDetail = levelData.split("<tr><td>");
            for (int i = 1; i < splitResultDetail.length; i++) {
                String name = splitResultDetail[i].split("</td><td>")[0];
                String winningCount = splitResultDetail[i].substring(0, splitResultDetail[i].indexOf("("));
                winningCount = winningCount.substring(winningCount.lastIndexOf(">") + 1).replace(",", "");
                String prizeAmount = splitResultDetail[i].split("</em>")[0];
                prizeAmount = prizeAmount.substring(prizeAmount.lastIndexOf(">") + 1).replace(",", "");
                LotteryDrawPrizeItem lotteryDrawPrizeItem = new LotteryDrawPrizeItem();
                lotteryDrawPrizeItem.setName(name);
                lotteryDrawPrizeItem.setWinningCount(winningCount);
                lotteryDrawPrizeItem.setPrizeAmount(prizeAmount);
                resultDetail.add(lotteryDrawPrizeItem);
            }
			logger.info(logHeader+"解析开奖详情:"+resultDetail);

            if (resultDetail.isEmpty()) return null;
			lotteryDraw = new LotteryDraw();
			lotteryDraw.setPhase(phase);
			lotteryDraw.setResult(result);
			lotteryDraw.setTimeDraw(CoreFetcherUtils.formatTimeDraw(timeDraw));
			lotteryDraw.setJackpot(jackpot);
			lotteryDraw.setVolumeOfSales(volumeOfSales);
			lotteryDraw.setLotteryType(getLotteryType());
			lotteryDraw.setResultDetail(resultDetail);

			logger.info(logHeader+lotteryDraw.getLotteryOpenResultLogMsg());
		}else{
			logger.error(logHeader+"页面开奖详情数据不存在");
		}
		if(lotteryDraw==null){
			logger.info(logHeader+"未抓取到相关开奖结果信息,返回null==");
		}
		logger.info(logHeader+"结束==");
		return lotteryDraw;
	}

	@Override
	protected String getResultDetailUrl(String phase) {
		if (phase != null && phase.trim().length() > 0) {
			return String.format(historyUrlMap.get(this.getLotteryType()), phase);
		}
        return null;
	}

	@Override
	protected String getResultUrl(String phase) {
		return null;
	}
}
